package com.zeratul.common.log.handler;

import cn.hutool.core.util.ObjectUtil;
import org.slf4j.MDC;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.GenericApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.ConfigurableEnvironment;

import static com.zeratul.common.core.constant.MdcConstants.*;


/**
 * 日志文件名 - 动态设置处理器
 *
 * 基于ApplicationEnvironmentPreparedEvent事件（环境配置准备事件），动态获取当前服务的名称，作为日志文件名
 * 并且通过MDC动态设置到log4j2的上下文中
 */
public class LogFileNameEventHandler implements GenericApplicationListener {

    /**
     * 判断是否支持当前事件
     * @param eventType
     * @return
     */
    @Override
    public boolean supportsEventType(ResolvableType eventType) {
        //判断当前的事件类型是否为需要的订阅的事件类型
        return eventType.isAssignableFrom(ApplicationEnvironmentPreparedEvent.class) ||
                eventType.isAssignableFrom(ApplicationPreparedEvent.class);
    }

    /**
     * 事件处理方法
     * @param event
     */
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent envPreEvent) {
            //获取当前SpringBoot加载好的环境
            ConfigurableEnvironment environment = envPreEvent.getEnvironment();
            //获取环境配置
            String microName = environment.getProperty(APPLICATION_NAME_KEY);
            if (ObjectUtil.isEmpty(microName)) {
                //设置默认日志文件名称
                microName = DEFAULT_FILE_NAME;
            }
            //放入MDC
            MDC.put(FILE_NAME, microName);
        } else if (event instanceof ApplicationPreparedEvent serPreEvent) {
            //清除MDC
            MDC.clear();
        }
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 19;
    }
}
